﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection;
using System.Windows;
using System.Windows.Controls;
using Caliburn.Micro;
using GTServices.WPF.Client.Controls;
using GTServices.WPF.Client.ViewModels; 
using GTServices.Entities;
using GTServices.Model;
using GTServices.Model.Extensions;
using ICSharpCode.AvalonEdit.Search;
using GTServices.WPF.Client.CoRoutines;
using System.Windows.Input;
using System.Windows.Interactivity;

namespace GTServices.WPF.Client.ViewModels
{
    
    public  class MatchInfoEditorViewModel : Screen
    {

        private MatchInfo _matchInfo;
        public MatchInfo MatchInfo
        {
            get { return _matchInfo; }
            set { _matchInfo = value;
                  UpdateEditor();
                  NotifyOfPropertyChange(() => MatchInfo);
            }
        }

        private String _searchText;
        public String SearchText
        {

            get { return _searchText; }
            set { _searchText = value; NotifyOfPropertyChange(() => SearchText); }
        }

        public AvalonEditControl Editor { get; set; }
        public SearchPanel SearchPanel { get; set; }

        public MatchInfoEditorViewModel()
        {
            this.Editor = new AvalonEditControl();

            this.Editor.TextArea.DefaultInputHandler.NestedInputHandlers.Add(new SearchInputHandler(this.Editor.TextArea));

            //Adding a Ctrl+s to the editor for "GTSearching"
            Command c = new Command((x) => true, (x) =>
            {
                GTSearch(); 
            });


            KeyGesture OpenKeyGesture = new KeyGesture(Key.S,
                                                       ModifierKeys.Control);
            KeyBinding OpenCmdKeybinding = new KeyBinding(c, OpenKeyGesture);

            this.Editor.InputBindings.Add(OpenCmdKeybinding);
            NotifyOfPropertyChange(() => Editor);

            this.SearchPanel = new SearchPanel();
            this.SearchPanel.Attach(Editor.TextArea);
            this.DisplayName = "MatchInfo Details";
            NotifyOfPropertyChange(() => DisplayName); 
            NotifyOfPropertyChange(() => SearchPanel);
        }
        public void UpdateEditor()
        {
            if (_matchInfo != null)
            {
                if (Editor.FileInfo != _matchInfo.FileInfo)
                {
                    Editor.FileInfo = _matchInfo.FileInfo;

                }
                var ln = this.Editor.Document.GetLineByNumber(_matchInfo.LineNumber);
                Editor.TextArea.Caret.Line = ln.LineNumber;
                Editor.ScrollTo(ln.LineNumber, 0);
                Editor.Select(ln.Offset, ln.Length);
            }
        }
        private AvalonEditControl GetTextEditor()
        {
            var view = this.GetView() as System.Windows.Controls.UserControl;
            if (view == null)
                return null;

            var t = GetFrameworkElementByType(view.Content.GetType(), typeof(AvalonEditControl));

            return t.GetValue(view.Content) as AvalonEditControl;
        }
        private FieldInfo GetFrameworkElementByType(Type fromType, Type toFetch)
        {
            List<FieldInfo> result;

            result = fromType.
              GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic).
              Where(i => typeof(FrameworkElement).IsAssignableFrom(i.FieldType)).ToList();

            var t = result.FirstOrDefault((x) => x.FieldType.FullName == toFetch.FullName);

            return t;
        }
        public void CopyFilePath()
        {
            if(MatchInfo != null && MatchInfo.FileInfo != null){
                try
                {
                    Clipboard.SetText(MatchInfo.FileInfo.FullName);
                }
                catch (Exception e)
                {
                    MessageBox.Show(e.Message);
                }
            }
        }
        public void CopySelected()
        {
            Editor.Copy(); 
        }
        public void GTSearch()
        {
            var searchDialog = new GTSearchDialogViewModel() { Path = this.MatchInfo.FileInfo.Path,
                                                               SearchPattern = Editor.SelectedText,
                                                               ByExtension = false,
                                                               Language = this.MatchInfo.Pattern.Language};

            GTWindowManager.Instance.ShowWindow(searchDialog, 500, 300);
        }
    }
}
